
// 1.

// import { useRef,useState } from 'react';

// function Parent() {
//   console.log('render Parent');
  
//   const inputRef = useRef(null);
//   const [count, setCount] = useState(0);
//   return (
//     <div>
//          <input ref={inputRef} type="text" />
//          <button onClick={() => inputRef.current.focus()}>Focus</button>
//          <div>count: {count}</div>
//          <button onClick={() => setCount(count+1)}>加1</button>
//     </div>
//   );
// }
// export default  Parent


// 2.ref记忆上一次渲染结果
// import { useRef,useState,useEffect } from 'react';
// function Counter() {
//   console.log('render Counter');
//   const [count, setCount] = useState(0);
//   const prevCountRef = useRef(0);

//   useEffect(() => {
//     console.log(count, '执行useEffect');
    
//     prevCountRef.current = count; // 保存当前值到 ref
//   }, [count]);

//   const prevCount = prevCountRef.current; // 获取上一次的值

//   return (
//     <div>
//       <p>现在: {count}, 之前: {prevCount}</p>
//       <button onClick={() => setCount(count + 1)}>增加</button>
//     </div>
//   );
// }
// export default  Counter

// 3.useRef会不会触发渲染更新
// import React, { useState, useRef, useEffect } from 'react';

// function Counter() {
//   console.log('render Counter');
//   const [count, setCount] = useState(0); // 使用 useState 管理 count
//   const refCount = useRef(0);            // 使用 useRef 来保存另一个计数器

//   const incrementStateCount = () => {
//     setCount(count + 1);
//   };

//   const incrementRefCount = () => {
//     refCount.current += 1;
//     console.log('RefCount:', refCount.current);
//   };

//   useEffect(() => {
//     console.log('Component rendered with count:', count);
//   });

//   return (
//     <div>
//       <p>State Count: {count}</p>
//       <button onClick={incrementStateCount}>Increment State Count</button>

//       <p>Ref Count: {refCount.current}</p>
//       <button onClick={incrementRefCount}>Increment Ref Count</button>
//     </div>
//   );
// }

// export default Counter

// 3.清除定时器

// import React, { useState, useRef, useEffect } from 'react';

// function TimerComponent() {
//   const [seconds, setSeconds] = useState(0);
//   const timerRef = useRef(null); // 存储定时器 ID

//   useEffect(() => {
//     timerRef.current = setInterval(() => {
//       setSeconds((s) => s + 1);
//     }, 1000);

//     return () => {
//       clearInterval(timerRef.current); // 卸载时清理定时器
//     };
//   }, []);

//   return (
//     <div>
//       <p>已运行时间：{seconds} 秒</p>
//       <button onClick={() => clearInterval(timerRef.current)}>停止计时器</button>
//     </div>
//   );
// }
// export default TimerComponent

// 4.是否首次加载

// import React, { useState, useEffect, useRef } from 'react';

// function FirstRenderCheck() {
//   const isFirstRender = useRef(true); // 初始设为 true

//   useEffect(() => {
//     if (isFirstRender.current) {
//       console.log('这是首次渲染');
//       isFirstRender.current = false; // 首次渲染后改为 false
//     } else {
//       console.log('这是更新后的渲染');
//     }
//   });

//   const [count, setCount] = useState(0);

//   return (
//     <div>
//       <p>点击次数: {count}</p>
//       <button onClick={() => setCount(count + 1)}>点我</button>
//     </div>
//   );
// }

// export default FirstRenderCheck

// 5.缓存

// import React, { useRef } from 'react';

// function CacheExpensiveData() {
//   const dataRef = useRef(null);

//   // 只有在首次调用时才会执行 createExpensiveData()
//   if (dataRef.current === null) {
//     dataRef.current = createExpensiveData();
//   }

//   return <div>{dataRef.current}</div>;
// }

// // 模拟一个耗性能的初始化函数
// function createExpensiveData() {
//   console.log('正在创建昂贵的数据...');
//   return '这是初始化数据';
// }

// export default CacheExpensiveData

// 6.在循环中操作 ref 可以使用回调函数写法，
// import { useState } from 'react';
// function App() {
//   const [list] = useState([
//     { id: 1, text: 'aaa' },
//     { id: 2, text: 'bbb' },
//     { id: 3, text: 'ccc' },
//   ]);
//   console.log(list, 'list');
//   return (
//     <div>
//       hello App
//       <br />
//       <ul>
//         {list.map((item) => {
//           return (
//             <li
//               key={item.id}
//               ref={(selfRef) => {
//                 selfRef.style.background = '#f0f';
//               }}
//             >
//               {item.text + 'hhh'}
//             </li>
//           );
//         })}
//       </ul>
//     </div>
//   );
// }
// export default App;

// 7.你需要将 ref 传递给一个子组件，需要 forwardRef 进行转发

// import { useRef, forwardRef } from 'react';
// const Head = forwardRef(function Head(props, ref) {
//   return (
//     <div>
//       <input type="text" ref={ref}></input>
//     </div>
//   );
// });
// function App() {
//   const refHead = useRef(null);
//   // 所以要改为，有记忆功能的ref
//   const handleClick = () => {
//     refHead.current.focus();
//     refHead.current.style.background = '#ff0';
//   };
//   return (
//     <div>
//       hello App
//       <button onClick={handleClick}>forwardRef操作</button>
//       <br />
//       <Head ref={refHead}></Head>
//     </div>
//   );
// }
// export default App;

// 8.为什么使用 useImperativeHandle？
// 控制暴露的内容：默认情况下，如果你将一个 ref 传递给一个子组件并使用 React.forwardRef，这个 ref 会指向子组件的 DOM 节点（对于函数组件，则是包裹它的 div 或其他标签）。然而，很多时候我们希望父组件能够访问的是子组件内部定义的一些方法或状态，而不是整个 DOM 节点。useImperativeHandle 允许你精确地控制哪些方法或属性可以通过 ref 暴露给父组件。
// 增强封装性：通过 useImperativeHandle，你可以隐藏子组件内部的实现细节，只暴露必要的接口给外部使用。这有助于保持良好的封装性，防止父组件依赖子组件的具体实现细节。
// 提供更清晰的 API：使用 useImperativeHandle 可以让你为子组件定义一个清晰、明确的 API，使得父组件可以更加直观地理解和使用这些暴露出来的功能。

import { useRef, forwardRef, useImperativeHandle } from 'react';
const Head = forwardRef(function Head(props, ref) {
  const inputRef = useRef(null);
  useImperativeHandle(ref, () => {
    return {
      focus() {
        inputRef.current.focus();
      },
      style() {
        inputRef.current.style.background = 'red';
      },
    };
  });
  return (
    <div>
      <input type="text" ref={inputRef}></input>
    </div>
  );
});
function App() {
  const refHead = useRef(null);
  // 所以要改为，有记忆功能的ref
  const handleClick = () => {
    refHead.current.focus();
    // refHead.current.style.background = '#ff0';//error
    refHead.current.style(); //correct
  };
  return (
    <div>
      hello App
      <button onClick={handleClick}>forwardRef操作</button>
      <br />
      <Head ref={refHead}></Head>
    </div>
  );
}
export default App;